package com.qpkj.oms.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.qpkj.common.constant.UserConstants;
import com.qpkj.common.core.domain.AjaxResult;
import com.qpkj.common.core.domain.entity.SysUser;
import com.qpkj.common.core.domain.model.LoginUser;
import com.qpkj.common.exception.ServiceException;
import com.qpkj.common.utils.DateUtils;
import com.qpkj.common.utils.SecurityUtils;
import com.qpkj.common.utils.StringUtils;
import com.qpkj.common.utils.bean.BeanUtils;
import com.qpkj.common.utils.bean.BeanValidators;
import com.qpkj.oms.domain.*;
import com.qpkj.oms.mapper.OmsProductCategoryMapper;
import com.qpkj.oms.mapper.OmsProductNeedsMapper;
import com.qpkj.oms.mapper.OmsStockRecoderMapper;
import com.qpkj.oms.parameter.ProductNeedVo;
import com.qpkj.oms.parameter.ProductSaveVo;
import com.qpkj.oms.parameter.StockVo;
import com.qpkj.oms.result.ProductResult;
import com.qpkj.system.service.impl.SysUserServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.qpkj.oms.mapper.OmsProductMapper;
import com.qpkj.oms.service.IOmsProductService;
import org.springframework.transaction.annotation.Transactional;

import static com.qpkj.common.core.domain.AjaxResult.error;

/**
 * 物料Service业务层处理
 *
 * @author ruoyi
 * @date 2022-12-20
 */
@Service
public class OmsProductServiceImpl implements IOmsProductService {
    private static final Logger log = LoggerFactory.getLogger(OmsProductServiceImpl.class);
    @Autowired
    private OmsProductMapper omsProductMapper;
    @Autowired
    private OmsProductNeedsMapper needsMapper;
    @Autowired
    private OmsProductCategoryMapper categoryMapper;
    @Autowired
    private OmsStockRecoderMapper stockRecoderMapper;
    @Autowired
    private OmsProductCategoryMapper omsProductCategoryMapper;

    /**
     * 查询物料
     *
     * @param productId 物料主键
     * @return 物料
     */
    @Override
    public ProductResult selectOmsProductByProductId(Long productId) {
        ProductResult result = new ProductResult();
        OmsProduct product = omsProductMapper.selectOmsProductByProductId(productId);
        BeanUtils.copyBeanProp(result, product);
        OmsProductNeeds needs = new OmsProductNeeds();
        needs.setProductId(productId);
        List<OmsProductNeeds> needsList = needsMapper.selectOmsProductNeedsList(needs);
        if (!ObjectUtils.isEmpty(needsList)) {
            result.setNeedsList(needsList);
        }
        // 查询分类
        OmsProductCategory category = categoryMapper.selectOmsProductCategoryByCategoryId(product.getProductCategory());
        OmsProductCategory category1 = categoryMapper.selectOmsProductCategoryByCategoryId(category.getParentId());
        if (!ObjectUtils.isEmpty(category)) {
            result.setProductCategory(category.getCategoryName());
            result.setCategoryParentId(category.getCategoryId());
        }
        if (!ObjectUtils.isEmpty(category1)) {
            result.setProductChildCategory(category1.getCategoryName());
            result.setCategoryId(category1.getCategoryId());
        }
        return result;
    }

    @Override
    public AjaxResult selectOmsProductByProductNo(String productNo,Integer type) {
        OmsProduct omsProduct = omsProductMapper.selectOmsProductByProductNo(productNo);
        if (ObjectUtils.isEmpty(omsProduct)) {
            return error("物料编号不存在！");
        }
        String categoryName = "";
        OmsProductCategory category = categoryMapper.selectOmsProductCategoryByCategoryId(omsProduct.getProductCategory());
        if (category.getParentId().equals(0L)) {
            // 一级分类
            categoryName = category.getCategoryName();
        } else {
            // ?
            OmsProductCategory category1 = categoryMapper.selectOmsProductCategoryByCategoryId(category.getParentId());
            categoryName = category1.getCategoryName();
        }
        // type与物料类型是否一致
        if (type != null) {
            if (type.equals(0)) {
                // 成品物料
                if (!categoryName.equals("半成品")&&!categoryName.equals("原材料")) {
                    return AjaxResult.error("物料编号与类型不匹配");
                }
            } else if (type.equals(1)) {
                // 半成品物料
                if (!categoryName.equals("原材料")) {
                    return AjaxResult.error("物料编号与类型不匹配");
                }
               /* if (!categoryName.equals("原材料")) {
                    return error("物料编号与类型不匹配");
                }*/
            } else {
                // 原材料物料
                if (!categoryName.equals("原材料")) {
                    return error("物料编号与类型不匹配");
                }
            }
        }
        return AjaxResult.success(omsProduct);
    }

    @Override
    public AjaxResult queryProductByName(String productName, Integer type) {
        OmsProduct omsProduct = omsProductMapper.selectProductByName(productName);
        if (ObjectUtils.isEmpty(omsProduct)) {
            return error("物料编号不存在！");
        }
        String categoryName = "";
        OmsProductCategory category = categoryMapper.selectOmsProductCategoryByCategoryId(omsProduct.getProductCategory());
        if (category.getParentId().equals(0L)) {
            // 一级分类
            categoryName = category.getCategoryName();
        } else {
            // ?
            OmsProductCategory category1 = categoryMapper.selectOmsProductCategoryByCategoryId(category.getParentId());
            categoryName = category1.getCategoryName();
        }
        // type与物料类型是否一致
        if (type != null) {
            if (type.equals(1)) {
                // 成品生产任务
                if (!categoryName.equals("成品")) {
                    return AjaxResult.error("物料编号与类型不匹配");
                }
               /* if (!categoryName.equals("原材料")) {
                    return error("物料编号与类型不匹配");
                }*/
            } else if (type.equals(2)) {
                // 备货半成品生产
                if (!categoryName.equals("半成品")) {
                    return AjaxResult.error("物料编号与类型不匹配");
                }
               /* if (!categoryName.equals("原材料")) {
                    return error("物料编号与类型不匹配");
                }*/
            } else {
                // 备货半成品包装，从成品里边拿
                if (!categoryName.equals("成品")) {
                    return error("物料编号与类型不匹配");
                }
            }
        }
        return AjaxResult.success(omsProduct);
    }

    @Override
    public AjaxResult queryProductByNo(String productNo, Integer type) {
        OmsProduct omsProduct = omsProductMapper.selectOmsProductByProductNo(productNo);
        if (ObjectUtils.isEmpty(omsProduct)) {
            return error("物料编号不存在！");
        }
        String categoryName = "";
        OmsProductCategory category = categoryMapper.selectOmsProductCategoryByCategoryId(omsProduct.getProductCategory());
        if (category.getParentId().equals(0L)) {
            // 一级分类
            categoryName = category.getCategoryName();
        } else {
            // ?
            OmsProductCategory category1 = categoryMapper.selectOmsProductCategoryByCategoryId(category.getParentId());
            categoryName = category1.getCategoryName();
        }
        // type与物料类型是否一致
        if (type != null) {
            if (type.equals(1)) {
                // 成品生产任务
                if (!categoryName.equals("成品")) {
                    return AjaxResult.error("物料编号与类型不匹配");
                }
               /* if (!categoryName.equals("原材料")) {
                    return error("物料编号与类型不匹配");
                }*/
            } else if (type.equals(2)) {
                // 备货半成品生产
                if (!categoryName.equals("半成品")) {
                    return AjaxResult.error("物料编号与类型不匹配");
                }
               /* if (!categoryName.equals("原材料")) {
                    return error("物料编号与类型不匹配");
                }*/
            } else {
                // 备货半成品包装，从成品里边拿
                if (!categoryName.equals("成品")) {
                    return error("物料编号与类型不匹配");
                }
            }
        }
        return AjaxResult.success(omsProduct);
    }

    /**
     * 查询物料列表
     *
     * @param omsProduct 物料
     * @return 物料
     */
    @Override
    public List<OmsProduct> selectOmsProductList(OmsProduct omsProduct) {
        return omsProductMapper.selectOmsProductList(omsProduct);
    }

    /**
     * 新增物料
     *
     * @param productSaveVo 物料
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertOmsProduct(ProductSaveVo productSaveVo) {
        try {
            OmsProduct omsProduct = new OmsProduct();
            BeanUtils.copyBeanProp(omsProduct, productSaveVo);
            omsProduct.setCreateTime(DateUtils.getNowDate());
            omsProduct.setProductSupplier(productSaveVo.getProductSupplier());
            if (UserConstants.NOT_UNIQUE.equals(checkomsProductNoUnique(omsProduct))) {
                return error("新增物料'" + omsProduct.getProductNo() + "'失败，该物料编号已存在");
            }
            // 生成唯一的物料编号
//            omsProduct.setProductNo(getProductNo());
            omsProductMapper.insertOmsProduct(omsProduct);
            if (!ObjectUtils.isEmpty(productSaveVo.getNeedVoList())) {
                productSaveVo.getNeedVoList().forEach(needVo -> {
                    SaveNeeds(omsProduct, needVo);
                });
            }
            return AjaxResult.success("新增物料成功！");
        } catch (Exception ex) {
            return error(ex.getMessage());
        }
    }

    /**
     * 校验物料编号是否唯一
     *
     * @param omsProduct 用户信息
     * @return 结果
     */
    public String checkomsProductNoUnique(OmsProduct omsProduct) {
        Long productId = StringUtils.isNull(omsProduct.getProductId()) ? -1L : omsProduct.getProductId();
        OmsProduct info = omsProductMapper.checkomsProductNoUnique(omsProduct.getProductNo());
        if (StringUtils.isNotNull(info) && info.getProductId().longValue() != productId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    private void SaveNeeds(OmsProduct omsProduct, ProductNeedVo needVo) {
        OmsProductNeeds needs = new OmsProductNeeds();
        needs.setProductId(omsProduct.getProductId());
        needs.setChildId(needVo.getProductId());
        needs.setProductNo(needVo.getProductNo());
        needs.setProductCustomer(omsProduct.getProductCustomer());
        needs.setProductName(needVo.getProductName());
        needs.setProductNum(needVo.getProductNum());
        needsMapper.insertOmsProductNeeds(needs);
    }
    private void updateNeeds(OmsProduct omsProduct, ProductNeedVo needVo) {
        OmsProductNeeds needs = new OmsProductNeeds();
        needs.setNeedId(needVo.getNeedId());
        needs.setProductId(omsProduct.getProductId());
        needs.setChildId(needVo.getProductId());
        needs.setProductNo(needVo.getProductNo());
        needs.setProductCustomer(omsProduct.getProductCustomer());
        needs.setProductName(needVo.getProductName());
        needs.setProductNum(needVo.getProductNum());
        needsMapper.updateOmsProductNeeds(needs);
    }

    /**
     * 修改物料
     *
     * @param omsProduct 物料
     * @return 结果
     */
    @Override
    public int updateOmsProduct(OmsProduct omsProduct) {
        omsProduct.setUpdateTime(DateUtils.getNowDate());
        return omsProductMapper.updateOmsProduct(omsProduct);
    }
    /**
     * 重写修改物料
     *
     * @param productSaveVo 物料
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int materialUpdate(ProductSaveVo productSaveVo) {
        try {
            OmsProduct omsProduct = new OmsProduct();
            BeanUtils.copyBeanProp(omsProduct, productSaveVo);
            omsProduct.setUpdateTime(DateUtils.getNowDate());
            omsProduct.setProductSupplier(productSaveVo.getProductSupplier());
            omsProductMapper.updateOmsProduct(omsProduct);
            if (!ObjectUtils.isEmpty(productSaveVo.getNeedVoList())) {
              //1.根据productId查询所有生产所需
//                OmsProductNeeds needs = new OmsProductNeeds();
//                needs.setProductId(omsProduct.getProductId());
//                List<OmsProductNeeds> list1 = needsMapper.selectOmsProductNeedsList(needs);
//                List<ProductNeedVo> list2= productSaveVo.getNeedVoList();
                productSaveVo.getNeedVoList().forEach(needVo -> {
                    Long needId= needVo.getNeedId();
                    if(needId!=null){
                        updateNeeds(omsProduct, needVo);
                    }else{
                        SaveNeeds(omsProduct, needVo);
                    }
                });
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return 1;
    }

    /**
     * 批量删除物料
     *
     * @param productIds 需要删除的物料主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteOmsProductByProductIds(Long[] productIds) {
        for (int i = 0; i < productIds.length; i++) {
            OmsProduct product = omsProductMapper.selectOmsProductByProductId(productIds[i]);
            product.setDelFlag("1");
            this.updateOmsProduct(product);
        }
        return 1;
    }

    /**
     * 删除物料信息
     *
     * @param productId 物料主键
     * @return 结果
     */
    @Override
    public int deleteOmsProductByProductId(Long productId) {
        return omsProductMapper.deleteOmsProductByProductId(productId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String importProduct(List<OmsProduct> productList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(productList) || productList.size() == 0) {
            throw new ServiceException("导入用户物料数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (OmsProduct product : productList) {
            try {
                product.setCreateBy(operName);
                product.setCreateTime(new Date());
                product.setProductNo(getProductNo());
                // 查询物料分类编号
                OmsProductCategory category = categoryMapper.selectOmsProductCategoryByCategoryName(product.getCategoryName());
                if (ObjectUtils.isEmpty(category)) {
                    throw new ServiceException("物料：" + product.getProductName() + "分类名称不存在，请检查！");
                }
                product.setProductCategory(category.getCategoryId());
                omsProductMapper.insertOmsProduct(product);
                // 录入生产所需
                // 生产所需编号与数量是否对应
                if (!ObjectUtils.isEmpty(product.getProductNeeds())) {
                    List<String> noList = Arrays.stream(product.getProductNeeds().split(",")).map(String::valueOf).collect(Collectors.toList());
                    List<Integer> numList = Arrays.stream(product.getProductNeedsCount().split(",")).map(Integer::parseInt).collect(Collectors.toList());
                    if (noList.size() != numList.size()) {
                        throw new ServiceException("物料：" + product.getProductName() + "生产所需物料与所需数量不对应！");
                    }
                    // 录入生产所需
                    for (int i = 0; i < noList.size(); i++) {
                        OmsProduct product1 = omsProductMapper.selectOmsProductByProductNo(noList.get(i));
                        OmsProductNeeds needs = new OmsProductNeeds();
                        needs.setChildId(product1.getProductId());
                        needs.setProductId(product.getProductId());
                        needs.setProductNum(numList.get(i));
                        needs.setProductName(product1.getProductName());
                        needs.setProductColour(product1.getProductColour());
                        needs.setProductNo(product1.getProductNo());
                        needsMapper.insertOmsProductNeeds(needs);
                    }
                }
                successNum++;
                successMsg.append("<br/>" + successNum + "、物料： " + product.getProductName() + " 导入成功");
                // 验证是否存在这个物料
                //OmsProduct p = omsProductMapper.selectOmsProductByProductNo(product.getProductNo());
                /*if (StringUtils.isNull(p)) {
                    product.setCreateBy(operName);
                    product.setProductNo(getProductNo());
                    // 查询物料分类编号
                    OmsProductCategory category = categoryMapper.selectOmsProductCategoryByCategoryName(product.getCategoryName());
                    if (ObjectUtils.isEmpty(category)) {
                        throw new ServiceException("物料：" + product.getProductName() + "分类名称不存在，请检查！");
                    }
                    product.setProductCategory(category.getCategoryId());
                    omsProductMapper.insertOmsProduct(product);
                    // 录入生产所需
                    // 生产所需编号与数量是否对应
                    if (!ObjectUtils.isEmpty(product.getProductNeeds())) {
                        List<String> noList = Arrays.stream(product.getProductNeeds().split(",")).map(String::valueOf).collect(Collectors.toList());
                        List<Integer> numList = Arrays.stream(product.getProductNeedsCount().split(",")).map(Integer::parseInt).collect(Collectors.toList());
                        if (noList.size() != numList.size()) {
                            throw new ServiceException("物料：" + product.getProductName() + "生产所需物料与所需数量不对应！");
                        }
                        // 录入生产所需
                        for (int i = 0; i < noList.size(); i++) {
                            OmsProduct product1 = omsProductMapper.selectOmsProductByProductNo(noList.get(i));
                            OmsProductNeeds needs = new OmsProductNeeds();
                            needs.setChildId(product1.getProductId());
                            needs.setProductId(product.getProductId());
                            needs.setProductNum(numList.get(i));
                            needs.setProductName(product1.getProductName());
                            needs.setProductColour(product1.getProductColour());
                            needs.setProductNo(product1.getProductNo());
                            needsMapper.insertOmsProductNeeds(needs);
                        }
                    }
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、物料： " + product.getProductName() + " 导入成功");
                } else if (isUpdateSupport) {
                   *//* product.setUpdateBy(operName);
                    this.updateOmsProduct(product);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、物料： " + product.getProductName() + " 更新成功");*//*
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、物料： " + product.getProductName() + " 已存在");
                }*/
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、物料： " + product.getProductName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    private String getProductNo() {
        String s = new SimpleDateFormat("yyMMdd").format(new Date());
        System.out.println(s);
        StringBuilder str = new StringBuilder();
        str.append(s);
        Random random = new Random();
        int min = 10000000;
        int max = 99999999;
        int sum = random.nextInt(max) % (max - min + 1) + min;
        str.append(sum);
        return "oms" + str.toString();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult productStock(StockVo stockVo) {
        OmsProduct product = omsProductMapper.selectOmsProductByProductId(stockVo.getProductId());
        if (ObjectUtils.isEmpty(product)) {
            return error("物料不存在！");
        }

        if (stockVo.getType().equals(0)) {
            int num = product.getProductStock() - stockVo.getStockNum();
            if (num < 0) {
                return error("库存不足！");
            }
            product.setProductStock(num);
        } else {
            product.setProductStock(product.getProductStock() + stockVo.getStockNum());
        }
        if (this.updateOmsProduct(product) > 0) {

            // 增加库存记录
            OmsStockRecoder recoder = new OmsStockRecoder();
            recoder.setRecoderDate(new Date());
            recoder.setRecoderName(product.getProductName());
            recoder.setCategoryName(product.getCategory().getCategoryName());
            recoder.setManuFactor(stockVo.getProductCustomer());
            recoder.setColour(product.getProductColour());
            recoder.setRecoderNo(product.getProductNo());
            recoder.setRecoderSku(product.getProductSku());
            if (stockVo.getType().equals(0)) {
                recoder.setRecoderChanage("-" + stockVo.getStockNum());
                recoder.setRecoderReason("物料出库");
            } else {
                recoder.setRecoderChanage("+" + stockVo.getStockNum());
                recoder.setRecoderReason("物料入库");
            }
            recoder.setRecoderOpter(getLoginUser().getUsername());
            stockRecoderMapper.insertOmsStockRecoder(recoder);
            return AjaxResult.success("操作成功！");
        }
        return error("操作失败！");
    }

    @Override
    public int queryWaringCount() {
        return omsProductMapper.queryWaringCount();
    }

    /**
     * 获取用户缓存信息
     */
    public LoginUser getLoginUser() {
        return SecurityUtils.getLoginUser();
    }
}
